package com.xique.park.controller.web;

import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.xique.common.core.constant.Constants;
import com.xique.common.core.domain.R;
import com.xique.common.core.enums.MngTypeEnum;
import com.xique.common.core.utils.SecurityUtils;
import com.xique.common.core.utils.poi.ExcelUtil;
import com.xique.common.core.web.controller.BaseController;
import com.xique.common.core.web.domain.AjaxResult;
import com.xique.common.core.web.domain.PageResult;
import com.xique.common.log.annotation.Log;
import com.xique.common.log.enums.BusinessType;
import com.xique.common.security.annotation.PreAuthorize;
import com.xique.park.bean.domain.ParkCar;
import com.xique.park.bean.request.app.*;
import com.xique.park.bean.request.web.car.*;
import com.xique.park.bean.request.web.parkcar.BlackCarRequest;
import com.xique.park.bean.request.web.parkcar.ParkCarRequest;
import com.xique.park.service.biz.service.IParkCarBizService;
import com.xique.park.service.service.IParkCarService;
import com.xique.park.service.service.ParkUpdateCarLogService;
import io.swagger.models.auth.In;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Date;
import java.util.List;

/**
 * 车辆管理controller
 *
 * @author lxl
 */
@Slf4j
@RestController
@RequestMapping("/web/car")
public class WebParkCarController extends BaseController {

    @Autowired
    private IParkCarBizService parkCarBizService;

    @Autowired
    private IParkCarService parkCarService;


    @Autowired
    private ParkUpdateCarLogService parkUpdateCarLogService;


    /**
     * 查询车辆列表
     */
    @PostMapping("/list")
    @PreAuthorize(hasPermi = "park:car:list")
    public AjaxResult parkCarList(@Validated @RequestBody ParkCarRequest request) {
        request.setParkId(SecurityUtils.getParkId());
        return parkCarBizService.getWebParkCarList(request);
    }

    /**
     * 查询车辆数据（不分页）
     */
    @PostMapping("/simple/list")
    @PreAuthorize(hasPermi = "park:car:list")
    public AjaxResult simpleParkCarList(@Validated @RequestBody ParkCar request) {
        request.setParkId(SecurityUtils.getParkId());
        return parkCarBizService.simpleParkCarList(request);
    }

    /**
     * 编辑车辆信息回显
     */
    @GetMapping("/info")
    @PreAuthorize(hasPermi = "park:car:query")
    public AjaxResult getWebParkCarInfo(Long carId) {
        return parkCarBizService.getWebParkCarInfo(carId);
    }

    /**
     * 查询某辆车详情
     */
    @GetMapping("/detail")
    @PreAuthorize(hasPermi = "park:car:query")
    public AjaxResult getParkCarInfoDetail(Long carId) {
        return parkCarBizService.getParkCarDetailInfo(carId);
    }

    /**
     * 查询某辆车续费页面具体信息
     */
    @GetMapping("/feeInfo")
    @PreAuthorize(hasPermi = "park:car:query")
    public AjaxResult getParkCarFeeInfo(Long carId) {
        return parkCarBizService.getParkCarFeeInfo(carId);
    }

    /**
     * 查询某辆车储值页面信息回显
     */
    @GetMapping("/depositInfo")
    @PreAuthorize(hasPermi = "park:car:query")
    public AjaxResult getParkCarDepositInfo(Long carId) {
        return parkCarBizService.getParkCarDepositInfo(carId);
    }

    /**
     * 添加车辆
     */
    @PreAuthorize(hasPermi = "park:car:add")
    @Log(title = "车辆管理", businessType = BusinessType.INSERT)
    @PostMapping("/add")
    public AjaxResult addParkCar(@Validated @RequestBody ParkCarAddRequest request) {
        request.setParkId(SecurityUtils.getParkId());
        return parkCarBizService.addWebParkCar(request);
    }

    /**
     * 编辑车辆
     */
    @PreAuthorize(hasPermi = "park:car:edit")
    @Log(title = "车辆管理", businessType = BusinessType.UPDATE)
    @PostMapping("/edit")
    public AjaxResult editParkCar(@Validated @RequestBody ParkCarEditRequest request) {
        request.setParkId(SecurityUtils.getParkId());
        return parkCarBizService.editWebParkCar(request);
    }

    /**
     * 车辆续期
     */
    @PreAuthorize(hasPermi = "park:car:edit")
    @Log(title = "车辆管理-续费", businessType = BusinessType.UPDATE)
    @PostMapping("/fee")
    public AjaxResult feeParkCar(@Validated @RequestBody ParkCarFeeRequest request) {
        return parkCarBizService.feeParkCar(request);
    }

    /**
     * 车辆续期
     */
    @PreAuthorize(hasPermi = "park:car:edit")
    @Log(title = "车辆管理-批量续费", businessType = BusinessType.UPDATE)
    @PostMapping("/batchFee")
    public AjaxResult batchFee(@Validated @RequestBody ParkCarBatchFeeRequest request) {
        return parkCarBizService.batchFeeParkCar(request);
    }

    /**
     * 删除车辆
     */
    @PreAuthorize(hasPermi = "park:car:remove")
    @Log(title = "车辆管理", businessType = BusinessType.DELETE)
    @DeleteMapping("/delete")
    public AjaxResult remove(@Validated @RequestBody ParkCarDeleteRequest request) {
        return parkCarBizService.delParkCar(request);
    }

    /**
     * 车辆批量删除
     */
    @PreAuthorize(hasPermi = "park:car:remove")
    @Log(title = "车辆管理-批量删除", businessType = BusinessType.DELETE)
    @DeleteMapping("/batchDelete")
    public AjaxResult batchDelete(@Validated @RequestBody ParkCarBatchDeleteRequest request) {
        return parkCarBizService.batchDeleteParkCar(request);
    }

    /**
     * 下载模板
     */
    @PostMapping("/importTemplate")
    public void importTemplate(HttpServletResponse response) throws IOException {
        parkCarBizService.importTemplate(response);
    }

    /**
     * 车辆导入
     */
    @Log(title = "车辆导入", businessType = BusinessType.IMPORT)
    @PreAuthorize(hasPermi = "park:car:import")
    @PostMapping("/importData")
    public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception {
        ExcelUtil<ParkCar> util = new ExcelUtil<>(ParkCar.class);
        List<ParkCar> parkCarList = util.importExcel(file.getInputStream());
        return parkCarBizService.importParkCarNew(parkCarList, updateSupport);
    }

    @Log(title = "车辆导出", businessType = BusinessType.EXPORT)
    @PreAuthorize(hasPermi = "park:car:export")
    @PostMapping("/export")
    public void export(HttpServletResponse response, ParkCar parkCar) throws IOException {
        parkCarBizService.export(parkCar, response);
    }

    @PreAuthorize(hasPermi = "park:car:edit")
    @Log(title = "车辆管理-储值", businessType = BusinessType.UPDATE)
    @PostMapping("/deposit")
    public AjaxResult deposit(@Validated @RequestBody ParkCarDepositRequest request) {
        return parkCarBizService.deposit(request);
    }

    @PreAuthorize(hasPermi = "parking:all:online")
    @Log(title = "车辆管理-下发", businessType = BusinessType.COMMAND)
    @PostMapping("/downOne")
    public AjaxResult downOne(@Validated @RequestBody ParkCarDownRequest request) {
        return parkCarBizService.downOne(request);
    }

    /**
     * 车辆批量下发
     */
    @PreAuthorize(hasPermi = "parking:all:online")
    @Log(title = "车辆管理-批量下发", businessType = BusinessType.COMMAND)
    @PostMapping("/batchDown")
    public AjaxResult batchDown(@Validated @RequestBody ParkCarDownRequest request) {
        return parkCarBizService.batchDown(request);
    }

    /**
     * 车辆全部下发
     */
    @PreAuthorize(hasPermi = "parking:all:online")
    @Log(title = "车辆管理-全部下发", businessType = BusinessType.COMMAND)
    @GetMapping("/downAll")
    public AjaxResult downAll() {
        return parkCarBizService.downAll();
    }

    /**
     * 车辆暂停
     */
    @PreAuthorize(hasPermi = "park:car:edit")
    @Log(title = "车辆管理-暂停", businessType = BusinessType.UPDATE)
    @DeleteMapping("/pause")
    public AjaxResult pause(@Validated @RequestBody ParkCarPauseRequest request) {
        return parkCarBizService.pauseParkCar(request);
    }

    /**
     * 查询某辆车续费记录列表
     */
    @PostMapping("/getFeeList")
    @PreAuthorize(hasPermi = "park:car:query")
    public AjaxResult getFeeList(@Validated @RequestBody ParkCarFeeListRequest request) {
        return parkCarBizService.getParkCarFeeList(request);
    }

    /**
     * 查询某辆车在场状态
     */
    @PostMapping("/getOnStatus")
    @PreAuthorize(hasPermi = "park:car:query")
    public AjaxResult getOnStatus(@Validated @RequestBody ParkCarOnStatusRequest request) {
        return parkCarBizService.getOnStatus(request);
    }

    /**
     * 计算月卡车应收金额
     */
    @PostMapping("/calFixedFee")
    public AjaxResult calFixedFee(@Validated @RequestBody ParkCarCalFixedFeeRequest request) {
        return parkCarBizService.calFixedFee(request);
    }

    /**
     * 黑名单车辆列表
     */
    @PostMapping("/blackList")
    public AjaxResult blackList(@RequestBody ParkCarRequest request) {
        request.setMngType(Long.valueOf(MngTypeEnum.BLACKLIST.getType()));
        request.setParkId(SecurityUtils.getParkId());
        PageResult pageResult = parkCarService.selectListByMngType(request);
        return AjaxResult.success(pageResult);
    }

    /**
     * 添加黑名单车辆
     */
    @PostMapping("/addBlack")
    public AjaxResult addBlack(@Validated @RequestBody BlackCarRequest request) {
        String beginTime = request.getBeginTime();
        String endTime = request.getEndTime();
        if (!StrUtil.equals(beginTime, Constants.FOREVER_STR) && !StrUtil.equals(endTime, Constants.FOREVER_STR)) {
            Date beginDate = DateUtil.parseDate(beginTime);
            Date endDate = DateUtil.parseDate(endTime);
            long dateBetween = DateUtil.between(beginDate, endDate, DateUnit.DAY, false);
            if (dateBetween < 0) {
                return AjaxResult.error("新增失败，截止日期不可大于起始日期");
            }
        }
        request.setParkId(SecurityUtils.getParkId());
        request.setUserId(SecurityUtils.getUserId());
        return parkCarService.saveBlackCar(request);
    }

    /**
     * 移除黑名单
     */
    @DeleteMapping("/removeBlack")
    public AjaxResult removeBlack(@RequestBody ParkCarDeleteRequest request) {
        request.setUserId(SecurityUtils.getUserId());
        request.setParkId(SecurityUtils.getParkId());
        return parkCarBizService.removeBlack(request);
    }

    /**
     * 删除超过了有效期的黑名单车辆
     */
    @DeleteMapping("/removeBlackExpire")
    public R<String> removeBlackExpire() {
        log.info("[车辆服务]-删除超过了有效期的黑名单车辆，开始时间：{}", DateUtil.now());
        parkCarBizService.removeBlackExpire();
        log.info("[车辆服务]-删除超过了有效期的黑名单车辆，结束时间：{}", DateUtil.now());
        return R.ok();
    }

    /**
     * 下发到了启用日期的黑名单车辆
     */
    @PostMapping("/downEnableBlackCar")
    public R<String> downEnableBlackCar() {
        log.info("[车辆服务]-下发到了启用日期的黑名单车辆，开始时间：{}", DateUtil.now());
        parkCarBizService.downEnableBlackCar();
        log.info("[车辆服务]-下发到了启用日期的黑名单车辆，结束时间：{}", DateUtil.now());
        return R.ok();
    }

    /*================================================================ 开元酒店定制接口 ====================================================*/

    @PostMapping("/visitorList")
    @PreAuthorize(hasPermi = "park:car:list")
    public AjaxResult parkVisitorCarList(@Validated @RequestBody ParkCarRequest request) {
        request.setParkId(SecurityUtils.getParkId());
        request.setOperator(SecurityUtils.getUserId());
        request.setMngType(3L);
        return parkCarBizService.getWebParkVisitorCarList(request);
    }

    /**
     * @description: 添加访客车（开元酒店定制接口）
     * @author: HdongSun
     * @date: 2022/8/23 9:29
     * @param: [request]
     * @return: com.xique.common.core.web.domain.AjaxResult
     **/
    @PreAuthorize(hasPermi = "park:car:add")
    @Log(title = "车辆管理(添加访客车（开元酒店定制接口）)", businessType = BusinessType.INSERT)
    @PostMapping("/addVisitorCar")
    public AjaxResult addVisitorCar(@RequestBody ParkVisitorCarAddRequest request) {
        request.setParkId(SecurityUtils.getParkId());
        return parkCarBizService.addVisitorCar(request);
    }

    /**
     * @description: 删除访客车（开元酒店定制接口）
     * @author: HdongSun
     * @date: 2022/8/23 9:36
     * @param: [request]
     * @return: com.xique.common.core.web.domain.AjaxResult
     **/
    @PreAuthorize(hasPermi = "park:car:remove")
    @Log(title = "车辆管理(删除访客车（开元酒店定制接口）)", businessType = BusinessType.DELETE)
    @DeleteMapping("/delVisitorCar")
    public AjaxResult delVisitorCar(ParkCarDeleteRequest request) {
        request.setParkId(SecurityUtils.getParkId());
        return parkCarBizService.delParkCar(request);
    }

    /*================================================================ 数据处理 ====================================================*/
    @PostMapping("/dataDeal")
    public AjaxResult dataDeal(Long id) {
        return parkCarBizService.dataDeal(id);
    }


    /**
     * 查询车辆变更记录
     * @param updateLogRequest
     * @return
     */
    @PostMapping("/updateCarLog")
    public AjaxResult selectUpdateCarLog(@Validated @RequestBody UpdateLogRequest updateLogRequest){
        return  parkUpdateCarLogService.selectUpdateCarLog(updateLogRequest);
    }

    /**
     * 查询车辆前后续期记录
     *
     * @param feeCarLogRequest
     * @return
     */
    @PostMapping("/delayCarLog")
    public AjaxResult selectDelayCarLog(@RequestBody FeeCarLogRequest feeCarLogRequest) {
        return parkCarBizService.selectDelayCarLog(feeCarLogRequest);
    }

    /**
     * 查询储值记录
     */
    @PostMapping("/depositLog")
    public AjaxResult selectDepositLog(@RequestBody DepositLogRequest request) {
        return parkCarBizService.selectDepositLog(request);
    }

    /**
     * 查询访客车具体记录
     */
    @GetMapping("log/{id}")
    public AjaxResult queryParkUpdateDetailInfo(@PathVariable int id){
        return parkUpdateCarLogService.queryParkUpdateDetailInfo(id);
    }
}
